package com.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.dto.JsonResult;
import com.filter.JwtAuthenticationTokenFilter;
import com.utils.HttpUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.jdbc.JdbcDaoImpl;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.sql.DataSource;

/**
 * @author Yadasu
 * @version 1.0
 * @date 2020/9/28 0028 17:16
 */
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, jsr250Enabled = true, securedEnabled = true)
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {


    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    @Qualifier("jdbcUseService")
    private UserDetailsService userDetailsService;

    @Override
    protected void configure(AuthenticationManagerBuilder authenticationManagerBuilder) {
        try {
            authenticationManagerBuilder
                    .userDetailsService(userDetailsService)
                    .passwordEncoder(passwordEncoder);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 不需要鉴权的路径配置
     *
     * @param web
     * @throws Exception
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().mvcMatchers("/api/user/login","/api/admin/role/menu", "/api/user/getInfo", "/api/user/logout", "/api/localStorage",
                "/api/uploadApp", "/api/version/updateVersion", "/api/version/search","/api/version","/api/version/clientUpdateVersion",
                "/api/version/WindowsUpdateVersion","/api/version/WindowsClientUpdateVersion")
                .antMatchers("/swagger-resources/**");
    }
    /**
     * 具体的访问策略配置
     *
     * @param httpSecurity
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        //关闭session
        httpSecurity.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        //关闭csrf
        httpSecurity.csrf().disable().logout()
                .logoutUrl("/api/user/logout")
                .deleteCookies("JSESSIONID", "auth-token")
                .permitAll();
        ;
        //允许跨域
        httpSecurity.cors();


        //接口请求需求权限
        httpSecurity.authorizeRequests()
                .mvcMatchers(HttpMethod.GET, "/api/**").hasRole("ADMIN")
                .mvcMatchers(HttpMethod.POST, "/api/**").hasRole("ADMIN")
                .mvcMatchers(HttpMethod.PUT, "/api/**").hasRole("ADMIN")
                .mvcMatchers(HttpMethod.PUT, "/api/**").hasRole("ADMIN")
                .mvcMatchers(HttpMethod.DELETE, "/api/**").hasRole("ADMIN");


        //权限不足
        httpSecurity.exceptionHandling()
                .accessDeniedHandler((request, response, accessDeniedException) -> {
                    HttpUtils.writeJson(response, JsonResult.buildFailure(403, "权限不足"), 403);
                });

        httpSecurity.addFilterBefore(new JwtAuthenticationTokenFilter(), UsernamePasswordAuthenticationFilter.class);


    }


}
